package com.ruoyi.web.controller.modules;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.Base64ToMultipart;
import com.ruoyi.common.utils.file.DownloadPdf;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.modules.domain.Credit;
import com.ruoyi.modules.domain.Unit;
import com.ruoyi.modules.service.CreditService;
import com.ruoyi.modules.service.UnitService;
import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.annotations.PdfRubberStampAnnotation;
import com.spire.pdf.annotations.appearance.PdfAppearance;
import com.spire.pdf.graphics.PdfImage;
import com.spire.pdf.graphics.PdfTemplate;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Date;
import java.util.List;

/**
 * 学生贷款申请基础信息
 *
 * @author tlgen
 */
@RestController
@RequestMapping("/student/credit/data")
public class CreditController extends BaseController
{
    @Autowired
    private CreditService creditService;

    @Autowired
    private UnitService unitService;

    /**
     * 查询学生贷款申请信息
     * @param credit
     * @return
     */
    @ApiOperation("查询学生贷款申请信息")
    @PreAuthorize("@ss.hasAnyPermi('student:mycredit:query,student:signcontract:query,hsien:signcontract:query,county:approve:query,bank:check:query,school:receipt:query,hsien:creditcheck:query')")
    @GetMapping("/list")
    public TableDataInfo list(Credit credit)
    {
        startPage();
        List<Credit> list = creditService.selectCreditList(credit);
        return getDataTable(list);
    }

    /**
     * 导出学生贷款申请信息
     * @param credit 贷款对象
     * @return
     */
    @Log(title = "导出学生贷款申请信息", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(Credit credit)
    {
        List<Credit> list = creditService.selectCreditList(credit);
        ExcelUtil<Credit> util = new ExcelUtil<Credit>(Credit.class);
        return util.exportExcel(list, "学生贷款申请信息数据");
    }

    /**
     * 查询学生贷款申请信息数据详细
     * @param creditId 贷款编号
     * @return
     */
    @GetMapping(value = "/{creditId}")
    public AjaxResult getInfo(@PathVariable Long creditId)
    {
        return AjaxResult.success(creditService.selectCreditById(creditId));
    }

    /**
     * 根据duringYear查询学生贷款申请信息
     * @param duringYear 年度
     * @param userName 用户名
     * @return
     */
    @GetMapping(value = "/year/{duringYear}/{userName}")
    public AjaxResult getOneByDuringYear(@PathVariable String duringYear, @PathVariable String userName)
    {
        Credit Credit = creditService.selectCreditByDuringYearAndUserName(duringYear, userName);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("data", Credit);
        return ajax;
    }

    /**
     * 查询当前用户的最新添加的一条记录
     * @return
     */
    @GetMapping(value = "/new/selectNewOne/{userName}")
    public AjaxResult selectNewCreateByUserName(@PathVariable String userName)
    {
        AjaxResult ajax = AjaxResult.success();
        ajax.put("data", creditService.selectNewCreateByUserName(userName));
        return ajax;
    }

    /**
     * 根据学生贷款申请信息类型查询学生贷款申请信息数据信息
     * @param userName
     * @return
     */
    @ApiOperation("根据用户名查询学生贷款申请信息")
    @GetMapping(value = "/name/{userName}")
    public AjaxResult selectCreditByName(@PathVariable String userName)
    {
        return AjaxResult.success(creditService.selectCreditByName(userName));
    }

    /**
     * 新增学生贷款申请信息类型
     * @param credit
     * @return
     */
    @ApiOperation("新增学生贷款申请信息")
    @Log(title = "学生贷款申请信息数据", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody Credit credit)
    {
        credit.setCreateBy(SecurityUtils.getUsername());
        return toAjax(creditService.insertCredit(credit));
    }

    /**
     * 修改保存学生贷款申请信息类型
     * @param credit
     * @return
     */
    @ApiOperation("修改学生贷款申请信息")
    @Log(title = "学生贷款申请信息数据", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody Credit credit)
    {
        credit.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(creditService.updateCredit(credit));
    }

    /**
     * 删除学生贷款申请信息类型
     * @param creditIds
     * @return
     */
    @ApiOperation("删除学生贷款申请信息")
    @Log(title = "学生贷款申请信息类型", businessType = BusinessType.DELETE)
    @DeleteMapping("/{creditIds}")
    public AjaxResult remove(@PathVariable Long[] creditIds)
    {
        return toAjax(creditService.deleteCreditByIds(creditIds));
    }


    /**
     * 在pdf上进行签章
     * @param creditId 贷款编号
     * @param unitId 签章编号
     * @return
     * @throws IOException
     */
    @PutMapping("/signatureToPdf")
    @Log(title = "在pdf上进行签章", businessType = BusinessType.UPDATE)
    public AjaxResult signatureToPdf(@RequestParam("creditId") Long creditId, @RequestParam("unitId") Long unitId) throws IOException {

        //创建PdfDocument对象，加载PDF测试文档
        PdfDocument doc = new PdfDocument();

        Credit credit = creditService.selectCreditById(creditId);
        String pdfPath = credit.getUploadWordPath();
        String fileName = credit.getUploadWordName();
        System.out.println(pdfPath); // /profile/word/2020/10/08/0187c87d7b5c6389792618bb6c499ba6.pdf
        System.out.println(fileName);

        // 先下载后拿到本地地址 因为 doc.loadFromFile 只接收本地地址
        String urlStr = "http://localhost:8080" + pdfPath;
        DownloadPdf downloadPdf = new DownloadPdf();
        downloadPdf.downLoadByUrl(urlStr, fileName, "E:\\");
        System.out.println("后端下载pdf到本地成功!");
        String newFilePath = "E:\\" + fileName;
        System.out.println("获取下载后的文件地址" + newFilePath); // 获取下载后的文件地址E:\201700208517_谭卢钢_基于springboot的速约车平台的设计与实现.docx
       // doc.loadFromFile("tlgen-ruoyi-vue/pdf/100面试题高级.pdf");
        doc.loadFromFile("E:\\" + fileName);
        /**
         * 解决 Evaluation Warning : The document was created with Spire.PDF for Java.
         */
        PdfPageBase pb = doc.getPages().add(); //新增一页
        doc.getPages().remove(pb); //去除第一页水印

        //获取文档第1页
        PdfPageBase page = doc.getPages().get(0);

        Unit couUnit = unitService.selectUnitById(unitId);
        String signature = couUnit.getUnitSignature();
        String signaturePath = "http://localhost:8080" + signature;
        String signatureName = couUnit.getUnitName();

        downloadPdf.downLoadByUrl(signaturePath, signatureName, "E:\\");
        System.out.println("后端下载印章图片到本地成功!");

        //加载印章图片
        PdfImage image = PdfImage.fromFile("E:\\" + signatureName);
       // PdfImage image = PdfImage.fromFile("tlgen-ruoyi-vue/signature/1600222639915.png");
        System.out.println("印章信息" + image);
        //获取印章图片的宽度和高度
        int width = image.getWidth();
        int height = image.getHeight();

        //创建PdfTemplate对象
        PdfTemplate template = new PdfTemplate(width, height);
        //将图片绘制到模板 -300是我自己生成的印章大小比300大 要在pdf上调整好大小
        template.getGraphics().drawImage(image, 260, 0, width-300, height-300);

        //创建PdfRubebrStampAnnotation对象，指定大小和位置
        Rectangle2D rect = new Rectangle2D.Float((float) (page.getActualSize().getWidth() - width - 10), (float) (page.getActualSize().getHeight() - height - 60), width, height);
        PdfRubberStampAnnotation stamp = new PdfRubberStampAnnotation(rect);

        //创建PdfAppearance对象
        PdfAppearance pdfAppearance = new PdfAppearance(stamp);
        //将模板应用为PdfAppearance的一般状态
        pdfAppearance.setNormal(template);
        //将PdfAppearance 应用为图章的样式
        stamp.setAppearance(pdfAppearance);

        //添加图章到PDF
        page.getAnnotationsWidget().add(stamp);

        //保存文档
        doc.saveToFile("E:\\学生贷款申请表签章.pdf", FileFormat.PDF);

        // 拿到已签章的pdf
        File newFile = new File("E:\\学生贷款申请表签章.pdf");

        // 将java.io.File转为MultipartFile
        FileInputStream inputStream = new FileInputStream(newFile);
        MockMultipartFile multipartFile = new MockMultipartFile("file", newFile.getName(), "text/plain", IOUtils.toByteArray(inputStream));
        System.out.println("将java.io.File转为MultipartFile成功后文件为:" + multipartFile);

        // 上传
        String uploadPdfWithSignaturePath = FileUploadUtils.upload(RuoYiConfig.getPdfWithSignature(), multipartFile);
        System.out.println("上传已签章的pdf文件路径为:" + uploadPdfWithSignaturePath);

        if (creditService.updatePdfWithSignature(creditId, uploadPdfWithSignaturePath, newFile.getName())) {
            AjaxResult ajax = AjaxResult.success();
            ajax.put("uploadPdfWithSignaturePath", uploadPdfWithSignaturePath);
            ajax.put("message", "pdf添加签章成功");
            // 更新
            credit.setIsSeal("是");
            credit.setPdfWithSignaturePath(uploadPdfWithSignaturePath);
            credit.setPdfWithSignatureName(newFile.getName());
            credit.setUpdateTime(new Date());
            credit.setCountyCheckStatus("已审批");
            creditService.updateCredit(credit);
            return ajax;
        }
        return AjaxResult.error("上传已签章的pdf文件失败!");
    }

    /**
     * 借款人上传电子签名
     * @param file 文件
     * @param creditId 贷款编号
     * @return
     * @throws IOException
     */
    @PutMapping("/updateFirstSignature")
    @Log(title = "借款人上传电子签名", businessType = BusinessType.UPDATE)
    public AjaxResult updateFirstSignature(@RequestParam("file") String file, @RequestParam("creditId") Long creditId) throws IOException {
        Credit credit = creditService.selectCreditById(creditId);

        // base64转MultipartFile, 其中base64用String来接收
        Base64ToMultipart base64ToMultipart = new Base64ToMultipart();
        MultipartFile newBase64ToMultipart = base64ToMultipart.base64ToMultipart(file);

        System.out.println("base64转MultipartFile成功,文件为: " + newBase64ToMultipart);

        String firstSignature = FileUploadUtils.upload(RuoYiConfig.getFirstSignature(), newBase64ToMultipart);

        // 将MultipartFile转为base64
        byte[] fileByte = null;
        fileByte = newBase64ToMultipart.getBytes();
        String voiceBase64 = Base64.getEncoder().encodeToString(fileByte);
        System.out.println("MultipartFile转为base64成功,文件为: " + voiceBase64);

        if (creditService.updateFirstSignature(creditId, firstSignature)) {
            AjaxResult ajax = AjaxResult.success();
            ajax.put("message", "上传电子签名成功!");
            ajax.put("firstSignature", voiceBase64);
            // 更新
            credit.setFirstSignature(voiceBase64);
            credit.setUpdateTime(new Date());
            creditService.updateCredit(credit);
            return ajax;
        }
        return AjaxResult.error("上传电子签名失败!");
    }


    /**
     * 县资助中心上传电子签名
     * @param file 文件
     * @param creditId 贷款编号
     * @return
     * @throws IOException
     */
    @PutMapping("/updateSecondSignature")
    @Log(title = "县资助中心上传电子签名", businessType = BusinessType.UPDATE)
    public AjaxResult updateSecondSignature(@RequestParam("file") String file, @RequestParam("creditId") Long creditId) throws IOException {
        Credit credit = creditService.selectCreditById(creditId);

        // base64转MultipartFile, 其中base64用String来接收
        Base64ToMultipart base64ToMultipart = new Base64ToMultipart();
        MultipartFile newBase64ToMultipart = base64ToMultipart.base64ToMultipart(file);

        System.out.println("base64转MultipartFile成功,文件为: " + newBase64ToMultipart);

        String secondSignature = FileUploadUtils.upload(RuoYiConfig.getSecondSignature(), newBase64ToMultipart);

        // 将MultipartFile转为base64
        byte[] fileByte = null;
        fileByte = newBase64ToMultipart.getBytes();
        String voiceBase64 = Base64.getEncoder().encodeToString(fileByte);
        System.out.println("MultipartFile转为base64成功,文件为: " + voiceBase64);

        if (creditService.updateSecondSignature(creditId, secondSignature)) {
            AjaxResult ajax = AjaxResult.success();
            ajax.put("message", "上传电子签名成功!");
            ajax.put("secondSignature", voiceBase64);
            // 更新
            credit.setSecondSignature(voiceBase64);
            credit.setUpdateTime(new Date());
            creditService.updateCredit(credit);
            return ajax;
        }
        return AjaxResult.error("上传电子签名失败!");
    }

    /**
     * 上传录取通知书
     * @param file 文件
     * @param creditId 贷款编号
     * @return
     * @throws IOException
     */
    @Log(title = "上传录取通知书", businessType = BusinessType.UPDATE)
    @PostMapping("/letter")
    public AjaxResult updateLetterOfAdmission(@RequestParam("letterOfAdmission") MultipartFile file, @RequestParam("creditId") Long creditId, @RequestParam("userName") String userName) throws IOException
    {
        AjaxResult ajax = AjaxResult.success();
        if (creditId != 0) {
            Credit credit = creditService.selectCreditById(creditId);
            String letterOfAdmissionPath = FileUploadUtils.upload(RuoYiConfig.getLetterOfAdmission(), file);
            creditService.updateLetterOfAdmission(creditId, letterOfAdmissionPath);

            ajax.put("letterOfAdmissionPath", letterOfAdmissionPath);
            // 更新
            credit.setLetterOfAdmission(letterOfAdmissionPath);
            credit.setUpdateTime(new Date());
            creditService.updateCredit(credit);
            return ajax;

        } else {
            String letterOfAdmissionPath = FileUploadUtils.upload(RuoYiConfig.getLetterOfAdmission(), file);
            //判断是否有一条记录现在只有主键id和identityPathOfFront两个字段
            Credit creditAlready = creditService.selectNewCreateByUserName(userName);
            String identityPathOfFront = creditAlready.getIdentityPathOfFront();
            String cardIdentity = creditAlready.getCardIdentity();
            if (StringUtils.isNotEmpty(identityPathOfFront) && StringUtils.isNotEmpty(cardIdentity)) {
                // 添加
                creditAlready.setLetterOfAdmission(letterOfAdmissionPath);
                creditService.insertCredit(creditAlready);
                // 查询最新添加的记录
                Credit creditVo = creditService.selectNewCreateByUserName(userName);
                System.out.println("保存了一条记录，该记录现在只有主键id和letterOfAdmissionPath两个字段");
                System.out.println(creditVo);
                creditService.updateCredit(creditVo);
                ajax.put("msg", "录取通知书上传成功!");
            } else {
                creditAlready.setLetterOfAdmission(letterOfAdmissionPath);
                creditService.updateCredit(creditAlready);
                ajax.put("msg", "录取通知书上传成功!");
            }
        }
        return ajax;
    }

    /**
     * 上传贫困材料证明
     * @param file 文件
     * @param creditId 贷款编号
     * @return
     * @throws IOException
     */
    @Log(title = "上传贫困材料证明", businessType = BusinessType.UPDATE)
    @PostMapping("/cer")
    public AjaxResult updateCertificat(@RequestParam("certificat") MultipartFile file, @RequestParam("creditId") Long creditId, @RequestParam("userName") String userName) throws IOException
    {
        AjaxResult ajax = AjaxResult.success();
        if (creditId != 0) {
            Credit credit = creditService.selectCreditById(creditId);
            String certificatPath = FileUploadUtils.upload(RuoYiConfig.getCertificat(), file);
            creditService.updateLetterOfAdmission(creditId, certificatPath);
            ajax.put("certificatPath", certificatPath);
            // 更新
            credit.setCertificat(certificatPath);
            credit.setUpdateTime(new Date());
            creditService.updateCredit(credit);
            return ajax;
        } else {
            String certificatPath = FileUploadUtils.upload(RuoYiConfig.getCertificat(), file);
            //判断是否有一条记录现在只有主键id和certificatPath两个字段
            Credit creditAlready = creditService.selectNewCreateByUserName(userName);
            String identityPathOfFront = creditAlready.getIdentityPathOfFront();
            String cardIdentity = creditAlready.getCardIdentity();
            if (StringUtils.isNotEmpty(identityPathOfFront) && StringUtils.isNotEmpty(cardIdentity)) {
                // 添加
                creditAlready.setCertificat(certificatPath);
                creditService.insertCredit(creditAlready);
                // 查询最新添加的记录
                Credit creditVo = creditService.selectNewCreateByUserName(userName);
                System.out.println("保存了一条记录，该记录现在只有主键id和certificatPath两个字段");
                System.out.println(creditVo);
                creditService.updateCredit(creditVo);
                ajax.put("msg", "贫困材料证明上传成功!");
            } else {
                creditAlready.setCertificat(certificatPath);
                creditService.updateCredit(creditAlready);
                ajax.put("msg", "贫困材料证明上传成功!");
            }
        }
        return ajax;
    }

    /**
     * 上传家庭户口本
     * @param file 文件
     * @param creditId 贷款编号
     * @return
     * @throws IOException
     */
    @Log(title = "上传家庭户口本", businessType = BusinessType.UPDATE)
    @PostMapping("/house")
    public AjaxResult updateHouseholdRegistrationBook(@RequestParam("householdRegistrationBook") MultipartFile file, @RequestParam("creditId") Long creditId, @RequestParam("userName") String userName) throws IOException
    {
        AjaxResult ajax = AjaxResult.success();
        if (creditId != 0) {
            Credit credit = creditService.selectCreditById(creditId);
            String householdRegistrationBookPath = FileUploadUtils.upload(RuoYiConfig.getHouseholdRegistrationBook(), file);
            creditService.updateLetterOfAdmission(creditId, householdRegistrationBookPath);
            ajax.put("householdRegistrationBookPath", householdRegistrationBookPath);
            // 更新
            credit.setHouseholdRegistrationBook(householdRegistrationBookPath);
            credit.setUpdateTime(new Date());
            creditService.updateCredit(credit);
            return ajax;
        }  else {
            String householdRegistrationBookPath = FileUploadUtils.upload(RuoYiConfig.getHouseholdRegistrationBook(), file);
            //判断是否有一条记录现在只有主键id和certificatPath两个字段
            Credit creditAlready = creditService.selectNewCreateByUserName(userName);
            String identityPathOfFront = creditAlready.getIdentityPathOfFront();
            String cardIdentity = creditAlready.getCardIdentity();
            if (StringUtils.isNotEmpty(identityPathOfFront) && StringUtils.isNotEmpty(cardIdentity)) {
                // 添加
                Credit credit = new Credit();
                credit.setHouseholdRegistrationBook(householdRegistrationBookPath);
                creditService.insertCredit(credit);
                // 查询最新添加的记录
                Credit creditVo = creditService.selectNewCreateByUserName(userName);
                System.out.println("保存了一条记录，该记录现在只有主键id和householdRegistrationBookPath两个字段");
                System.out.println(creditVo);
                creditService.updateCredit(creditVo);
                ajax.put("msg", "家庭户口本上传成功!");
            } else {
                creditAlready.setHouseholdRegistrationBook(householdRegistrationBookPath);
                creditService.updateCredit(creditAlready);
                ajax.put("msg", "家庭户口本上传成功!");
            }
        }
        return ajax;
    }
}
